﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SFWS.XHandler.Core;
using JKF.Substructure;
using JKF.Entities.Model;
using JKF.BusinessLayer.BLL;
using System.Data;
using JKF.Entities;
using JKF.BusinessLayer;
namespace JKF.HandlerLayer.Stock
{
    public partial class Stock_InHandler:AHttpHandler
    {
        private static bllSTOCK_IN bllStock_In = new bllSTOCK_IN();
        public override void ProcessRequest()
        {
            //所有错误和异常将抛出异常.正常执行程序则在方法则返回数据
            try
            {
                this.Manager(Utils.GetActionName);
            }
            catch (Exception ex)
            {
                //将错误抛到客户端(以Json格式)
                Utils.ToClient(true, ex.Message);
                //写日志
                AppLogger.Log(ex.Message, ex);
            }
        }
        /// <summary>
        /// 产品/耗材入库
        /// </summary> 
        public void InsertStock_In()
        {
            try
            {
                var strScr = P("moduleObj");
                var clientObj = JsonSerializer.Deserialize<Stock_InTemp>(strScr);
                var productInfo = this.BuildStock_IninfoByJson(clientObj, false); 
                //添加
                bool reslt = bllStock_In.TransationSql(BuildStock_In_InsertSqlByModel(productInfo));
                //写入日志表
                AppendLog(productInfo, null, LogType.Add);
                // 执行入库时，需要同步更新dbo.STOCK_AMOUNT 表中记录 
                Response.Write(JsonSerializer.Serialize(
                    new ResponseInf { 
                        MessageCode = "Ok", Message = "入库成功.", 
                        Data = new { IN_KEY = productInfo.IN_KEY, IN_NO = productInfo.IN_NO, USER_NAME = bllSYS_USER.CurrentUser.REAL_NAME}, 
                        Success =  reslt
                    }));
            }
            catch (Exception exp)
            {
                Response.Write(JsonSerializer.Serialize(new ResponseInf { MessageCode = "Error", Message = exp.Message.FilterJs() }));
            }
        }
        /// <summary>
        /// 产品/耗材入库编辑
        /// </summary>
        public void EditStock_In()
        {
            try
            {
                var strScr = P("moduleObj");
                var clientObj = JsonSerializer.Deserialize<Stock_InTemp>(strScr);
                var productInfo = this.BuildStock_IninfoByJson(clientObj, true);
                // 修改入库时，(暂时保留，以便后续用)需要同步更新dbo.STOCK_AMOUNT 表中记录 
                string stock_amount_update_sql = string.Format(" update dbo.STOCK_AMOUNT set PRODUCT_NUMS=PRODUCT_NUMS+{0}-{1} where PRODUCT_KEY='{2}' and SHOP_CODE='{3}' ;", productInfo.PRODUCT_NUMS, productInfo.OLD_PRODUCT_NUMS, productInfo.PRODUCT_KEY, productInfo.SHOP_CODE);
                string stock_in_update_sql = string.Format(" update dbo.STOCK_IN set PRODUCT_NUMS={0},DATE_IN='{1}',MEMO='{2}',DATE_UPDATE='{3}' where IN_KEY='{4}'", productInfo.PRODUCT_NUMS, productInfo.DATE_IN, productInfo.MEMO, productInfo.DATE_UPDATE,productInfo.IN_KEY);
                //1.先获取原来实体
                var serverObj = bllStock_In.GetModel(productInfo.IN_KEY);
                //修改
                bool reslt = bllStock_In.TransationSql(stock_in_update_sql+stock_amount_update_sql);
                
                //写日志
                AppendLog(BuildStock_InTemp(serverObj), productInfo, LogType.Edit);
                Response.Write(JsonSerializer.Serialize(
                    new ResponseInf
                    {
                        MessageCode = "Ok",
                        Message = "修改成功.",
                        Data = new { IN_KEY = productInfo.IN_KEY, IN_NO = productInfo.IN_NO, USER_NAME = bllSYS_USER.CurrentUser.REAL_NAME },
                        Success = reslt
                    }));
            }
            catch (Exception exp)
            {
                Response.Write(JsonSerializer.Serialize(new ResponseInf { MessageCode = "Error", Message = exp.Message.FilterJs() }));
            }
        }
        /// <summary>
        /// 获取每个店铺的入库列表数据
        /// </summary>
        public void GetSTOCK_INS()
        {
            var obj = new PagerList();

            int pageCount = 0;
            int rowCount = 0;

            if (P("isExport") == "1")
            {//入库单号	产品类别	产品名称	入库数量	备注	入库日期

                DataTable dt = bllStock_In.GetStock_InsBLL(P("NAME"), bllSYS_USER.CurrentUser.SHOP_CODE, P("PRODUCT_KEY"), P("PRODUCT_NUMS"), P("IN_NO"), P("REAL_NAME"), P("MEMO"), P("DATA_START"), P("DATA_END"), P("PageIndex").ToInt32(), -1, ref pageCount, ref rowCount);

                IDictionary<string, string> columns = new Dictionary<string, string>();
                columns.Add("IN_NO", "入库单号");
                columns.Add("SORT_NAME", "产品类别");
                columns.Add("NAME", "产品名称");
                columns.Add("PRODUCT_NUMS", "入库数量");
                columns.Add("MEMO", "备注");
                columns.Add("DATE_IN", "入库日期"); 
                Excel.Export("产品入库记录", dt, columns, Response, Excel.PageType.handler);
            }
            else
            {
                //从视图中获取： 
                obj.Entity = from a in bllStock_In.GetStock_InsBLL(P("NAME"), bllSYS_USER.CurrentUser.SHOP_CODE, P("PRODUCT_KEY"), P("PRODUCT_NUMS"), P("IN_NO"), P("REAL_NAME"), P("MEMO"), P("DATA_START"), P("DATA_END"), P("PageIndex").ToInt32(), P("PageSize").ToInt32(), ref pageCount, ref rowCount).AsEnumerable()
                             select new
                             {//PRODUCT_KEY, NAME, MODEL, TYPE, IN_NO, DATE_IN, MEMO, SORT_NAME, SHOP_CODE, PRODUCT_NUMS, USER_CREATE, 
                                 IN_KEY = a.Field<Guid>("IN_KEY"),
                                 IN_NO = a.Field<string>("IN_NO"), //入库单号
                                 SORT_NAME = a.Field<string>("SORT_NAME"), //产品类别名称
                                 NAME = a.Field<string>("NAME"), //产品名称
                                 PRODUCT_NUMS = a.Field<int>("PRODUCT_NUMS"), //入库数量
                                 MEMO = a.Field<string>("MEMO"), //备注
                                 USER_CREATE = a.Field<string>("USER_CREATE"), //操作员姓名
                                 DATE_CREATE = (a.Field<DateTime>("DATE_CREATE")).ToString("yyyy-MM-dd"),
                                 DATE_IN = (a.Field<DateTime>("DATE_IN")).ToString("yyyy-MM-dd HH:mm:ss")
                             };

                obj.RowCount = rowCount;
                obj.PageCount = pageCount;
                ResponseJsonObject = obj;
            }
        }
        /// <summary>
        /// 根据入库主键获取入库记录
        /// </summary>
        public void GetStock_InByCode()
        {
            try
            {
                var scid = P("moduleKey");
                var stock_in_model = bllStock_In.GetModel(new Guid(scid));
                var stock_in_product_model = new bllPRODUCT().GetModel(stock_in_model.PRODUCT_KEY);
                Response.Write(JsonSerializer.Serialize(
                    new ResponseInf { 
                        MessageCode = "Ok", Data = stock_in_model,
                        Mode = new  { SORT_KEY=stock_in_product_model.SORT_KEY,TYPE=stock_in_product_model.TYPE },
                        FormatString = stock_in_model.DATE_IN.ToString("yyyy-MM-dd HH:mm:ss") 
                    }));
            }
            catch (Exception exp)
            {
                Response.Write(JsonSerializer.Serialize(new ResponseInf { MessageCode = "Error", Message = exp.Message.FilterJs() }));
            }
        }
        /// <summary>
        /// 根据主键IN_KEY删除入库记录，采用逻辑删除.同时需要更新库存数量吗？
        /// </summary>
        public void DeleteSTOCK_IN()
        {
            try
            {
                var in_key = P("id");
                //1.逻辑删除入库记录，
                string stock_in_delete_sql = string.Format("update dbo.STOCK_IN set STATUS=9 where IN_KEY='{0}' ;",in_key);
                STOCK_INinfo model = bllStock_In.GetModel(new Guid(in_key));
                //2. 更新逻辑删除入库记录产品的库存信息
                string update_stock_amount_sql = string.Format("  update dbo.STOCK_AMOUNT set PRODUCT_NUMS=PRODUCT_NUMS-{0},  DATE_UPDATE='{1}' where PRODUCT_KEY='{2}'",model.PRODUCT_NUMS,DateTime.Now.ToString(),model.PRODUCT_KEY.ToString());
                bool reslt = bllStock_In.TransationSql(stock_in_delete_sql+update_stock_amount_sql);
                //写日志
                AppendLog(BuildStock_InTemp(model), null, LogType.Delete);
                Response.Write(JsonSerializer.Serialize(new ResponseInf { MessageCode = "Ok", Success = reslt, Data = in_key }));

            }
            catch (Exception exp)
            {
                Response.Write(JsonSerializer.Serialize(new ResponseInf { MessageCode = "Error", Message = exp.Message.FilterJs() }));
            }
        }
        /// <summary>
        /// 从Json对象构建对象
        /// </summary>
        /// <param name="shopInfo">实体对象</param>
        /// <param name="isEdit">是否为编辑</param>
        /// <returns></returns>
        public Stock_InTemp BuildStock_IninfoByJson(Stock_InTemp stock_in_info, bool isEdit)
        {
            var entity = new Stock_InTemp();
            if (!isEdit) // 添加
            {
                entity.IN_KEY = new Guid(DB.GetNewGuid(DB.HR)); //Guid.NewGuid();
                entity.IN_NO = this.BuildStock_In_NO(bllSYS_USER.CurrentUser.SHOP_CODE);//这个需要算法来自动生成
            }
            else // 修改
            {
                entity.IN_KEY = stock_in_info.IN_KEY;
                entity.IN_NO = stock_in_info.IN_NO;
            }

            entity.MEMO = stock_in_info.MEMO;
            entity.PRODUCT_KEY = stock_in_info.PRODUCT_KEY;
            entity.PRODUCT_NUMS = stock_in_info.PRODUCT_NUMS;
            entity.OLD_PRODUCT_NUMS = stock_in_info.OLD_PRODUCT_NUMS;
            entity.SHOP_CODE = bllSYS_USER.CurrentUser.SHOP_CODE; //当前用户店面编码
            entity.DATE_IN = stock_in_info.DATE_IN; 
            entity.USER_CREATE = bllSYS_USER.CurrentUser.USER_KEY; // 获取当前用户guid
            entity.DATE_CREATE = System.DateTime.Now.ToString();
            entity.DATE_UPDATE = System.DateTime.Now.ToString();
            return entity;
        }

        /// <summary>
        /// 组装实体
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        private Stock_InTemp BuildStock_InTemp(STOCK_INinfo model)
        {
            var temp = new Stock_InTemp();
            temp.DATE_CREATE = model.DATE_CREATE.ToString();
            temp.DATE_IN = model.DATE_IN.ToString();
            temp.DATE_UPDATE = model.DATE_UPDATE.ToString();
            temp.IN_KEY = model.IN_KEY;
            temp.IN_NO = model.IN_NO;
            temp.MEMO = model.MEMO;
            temp.PRODUCT_KEY = model.PRODUCT_KEY;
            temp.PRODUCT_NUMS = model.PRODUCT_NUMS.ToString(); 
            return temp;
        }
        /// <summary>
        /// 通过实体来构成插入语句
        /// </summary>
        /// <param name="stock_in_temp"></param>
        /// <returns></returns>
        public string BuildStock_In_InsertSqlByModel(Stock_InTemp stock_in_temp)
        {
            string stock_amount_sql = string.Empty;
            string stock_in_sql = string.Format("insert into dbo.STOCK_IN(IN_KEY, PRODUCT_KEY, IN_NO, PRODUCT_NUMS, DATE_IN, MEMO, SHOP_CODE, USER_CREATE, DATE_CREATE, DATE_UPDATE,STATUS) VALUES('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','1');", stock_in_temp.IN_KEY, stock_in_temp.PRODUCT_KEY, stock_in_temp.IN_NO, stock_in_temp.PRODUCT_NUMS, stock_in_temp.DATE_IN, stock_in_temp.MEMO, stock_in_temp.SHOP_CODE, stock_in_temp.USER_CREATE, stock_in_temp.DATE_CREATE, stock_in_temp.DATE_UPDATE);
            //1.先判断入库的产品dbo.STOCK_AMOUNT表中是否存在(product_key,shop_code)，如果存在则更新
            if (new bllSTOCK_AMOUNT().Exists(stock_in_temp.PRODUCT_KEY, stock_in_temp.SHOP_CODE))
            {
                stock_amount_sql = string.Format(" update dbo.STOCK_AMOUNT set PRODUCT_NUMS=PRODUCT_NUMS+{0}-{1} where PRODUCT_KEY='{2}' and SHOP_CODE='{3}'", stock_in_temp.PRODUCT_NUMS, stock_in_temp.OLD_PRODUCT_NUMS,stock_in_temp.PRODUCT_KEY,stock_in_temp.SHOP_CODE);
            }
            else
            {
                stock_amount_sql = string.Format(" insert into dbo.STOCK_AMOUNT(PRODUCT_KEY, SHOP_CODE, PRODUCT_NUMS, USER_CREATE, DATE_CREATE, DATE_UPDATE) VALUES('{0}','{1}','{2}','{3}','{4}','{5}')", stock_in_temp.PRODUCT_KEY, stock_in_temp.SHOP_CODE, stock_in_temp.PRODUCT_NUMS, stock_in_temp.USER_CREATE, stock_in_temp.DATE_CREATE, stock_in_temp.DATE_UPDATE);
            }
            return stock_in_sql + stock_amount_sql;
        }
        /// <summary>
        /// 生成入库单号
        /// </summary>
        /// <returns></returns>
        public string BuildStock_In_NO(string shop_code)
        {
            return bllStock_In.GetStock_IN_NOBLL(shop_code);
        }

        /// <summary>
        /// 获取产品类别与产品树型结构数据
        /// </summary>
        public void GetProduct_SortTree()
        {
            try
            {
                var oList = new bllPRODUCT().GetProduct_SortTreeBLL();
                Response.Write(new ResponseInf
                {
                    Data = oList,
                    Success = true
                }.ToJson());
            }
            catch (Exception exp)
            {
                Response.Write(new ResponseInf { Success = false, Message = exp.Message }.ToJson());
            }
        }
        /// <summary>
        /// 此类专用于前台传值从JSON对象构成实体对象
        /// </summary>
        public class Stock_InTemp
        {
            /// <summary>
            /// 主键，入库表
            /// </summary>
            public Guid IN_KEY{get;set;}
            /// <summary>
            /// 产品ID
            /// </summary>
            public Guid PRODUCT_KEY { get; set; }
            /// <summary>
            /// 入库单号
            /// </summary>
            public string IN_NO { get; set; }
            /// <summary>
            /// 入库数量（新）
            /// </summary>
            public string PRODUCT_NUMS { get; set; }
            /// <summary>
            /// 入库数量（旧）
            /// </summary>
            public string OLD_PRODUCT_NUMS { get; set; }
            /// <summary>
            /// 入库日期
            /// </summary>
            public string DATE_IN { get; set; }
            /// <summary>
            /// 备注
            /// </summary>
            public string MEMO { get; set; }
            /// <summary>
            /// 店铺
            /// </summary>
            public string SHOP_CODE { get; set; }
            /// <summary>
            /// 创建者ID
            /// </summary>
            public Guid USER_CREATE { get; set; }
            /// <summary>
            /// 创建日期
            /// </summary>
            public string DATE_CREATE { get; set; }
            /// <summary>
            /// 修改日期
            /// </summary>
            public string DATE_UPDATE { get; set; }
        }

        #region Log 
        /// <summary>
        /// 添加入库部分日志
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="logType">操作类型</param>
        private void AppendLog(Stock_InTemp from, Stock_InTemp to, LogType logType)
        {
            StringBuilder builder = new StringBuilder();
            if (logType == LogType.Add)
            { 
                bllSYS_LOG.SaveLog(SysConfig.STOCK_IN_MODULE_CODE,
                    SysConfig.STOCK_IN,
                    from.IN_KEY.ToString(),
                    string.Format("添加入库记录，入库单号：\"{0}\"产品key：\"{1}\"  入库数量：\"{2}\"",from.IN_NO,from.PRODUCT_KEY.ToString(),from.PRODUCT_NUMS),
                    SysConfig.Add,
                    BusinessBase.ClientIp);
                return;
            }
            if (logType == LogType.Edit)
            { 

                builder.AppendFormat("修改入库记录，入库单号：\"{0}\"  产品key：\"{1}\"  入库数量：\"{2}\" ", from.IN_NO, from.PRODUCT_KEY.ToString(), from.PRODUCT_NUMS);
                var bChange = false;
                if (from.DATE_IN != to.DATE_IN)
                {
                    builder.AppendFormat("入库日期 原值：\"{0}\"，现值：\"{1}\"", from.DATE_IN.ToString(), to.DATE_IN.ToString());
                    bChange = true;
                }
                if (from.PRODUCT_NUMS != to.PRODUCT_NUMS)
                {
                    builder.AppendFormat("入库数量 原值：\"{0}\"，现值：\"{1}\"", from.PRODUCT_NUMS, to.PRODUCT_NUMS);
                    bChange = true;
                }
                if (from.MEMO != to.MEMO)
                {
                    builder.AppendFormat("备注  原值:\"{0}\"，现值:\"{1}\"", from.MEMO, to.MEMO);
                    bChange = true;
                }
                if (bChange)
                {
                    bllSYS_LOG.SaveLog(SysConfig.STOCK_IN_MODULE_CODE,
                      SysConfig.STOCK_IN,
                      from.IN_KEY.ToString(),
                      builder.ToString(),
                      SysConfig.Edit,
                      BusinessBase.ClientIp);
                }
                return;
            }
            if (logType == LogType.Delete)
            {
                bllSYS_LOG.SaveLog(SysConfig.STOCK_IN_MODULE_CODE,
                      SysConfig.STOCK_IN,
                      from.IN_KEY.ToString(),
                      string.Format("删除入库记录，入库单号：\"{0}\"  产品key：\"{1}\"  入库数量：\"{2}\"", from.IN_NO, from.PRODUCT_KEY.ToString(), from.PRODUCT_NUMS),
                      SysConfig.Delete,
                      BusinessBase.ClientIp);
            }
        }
        #endregion
    }
}
